home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mm / mm-0.90 / newmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-18  |  8.1 KB  |  301 lines

  1. /*
  2.  * Copyright (c) 1986, 1990 by The Trustees of Columbia University in
  3.  * the City of New York.  Permission is granted to any individual or
  4.  * institution to use, copy, or redistribute this software so long as it
  5.  * is not sold for profit, provided this copyright notice is retained.
  6.  */
  7.  
  8. #ifndef lint
  9. static char *rcsid = "$Header: /f/src2/encore.bin/cucca/mm/tarring-it-up/RCS/newmail.c,v 2.6 90/11/26 19:44:23 howie Exp $";
  10. #endif
  11.  
  12. #include "mm.h"
  13. #include "parse.h"
  14. #include "cmds.h"
  15. #include "rd.h"
  16.  
  17. #define tempfile ".mm-newmail"
  18.  
  19. extern int check_interval;        /* polling interval */
  20.  
  21. /* return from newmail and set the alarm for next time */
  22. #ifndef HAVE_BSD_SIGNALS        /* XXX some other way? */
  23. #define nmreturn(val)   { alarm(0); return(val); }
  24. #else
  25. #define nmreturn(val)   { alarm(check_interval); return(val); }
  26. #endif
  27.  
  28. int gotmail=false, sawmail=false;
  29. static int in_here = false;
  30.  
  31. new_mail (quiet)
  32. int quiet;                /* explicit "check" or automatic? */
  33. {
  34.     keylist im;
  35.     static msgvec *nf;
  36.     msgvec *nmf;
  37.     int type;
  38.     keylist i;
  39.     static struct stat mailbuf;
  40.     struct stat oldbuf, sbuf;
  41.     extern int continuous_check;
  42.     int result = true;
  43.  
  44.     /* if they're busy and don't want to be bothered, don't interrupt */
  45.     if (quiet && !continuous_check && mode != MM_TOP_LEVEL)
  46.     nmreturn (result);
  47.  
  48.     oldbuf = mailbuf;
  49.     gotmail = false;
  50.  
  51.     check_mtime(cf, NULL);        /* don't bother reading in new mail */
  52.                     /*   if there is an inconsistency */
  53.     if (in_here) {            /* in the middle? */
  54.     if (cf->flags & MF_WRITERR) {    /* a write error, leave things alone */
  55.         if (!quiet)
  56.         fprintf(stderr,
  57.                "Cannot check for new mail until this file is saved\n");
  58.         nmreturn (result);
  59.     }
  60.     else {                /* write error was cleared */
  61.         unlink(nf->filename);
  62.         (*msg_ops[nf->type].close)(nf->filep);
  63.         free (nf->msgs);
  64.         free (nf);
  65.         nf = nil;
  66.         in_here = false;
  67.     }
  68.     }
  69.     if ((cf != NULL) && !(cf->flags & MF_RDONLY) && (cf->flags & MF_MAILBOX)) {
  70.     nmf = (msgvec *) malloc(sizeof(msgvec));
  71.     if (!nmf)
  72.         return;            /* XXX */
  73.     
  74.     bzero (nmf, sizeof (msgvec));
  75.  
  76.     sprintf(nmf->filename,"%s/%s", 
  77.         strcmp(".",mail_directory)?mail_directory:HOME, tempfile);
  78.     if (stat(nmf->filename,&sbuf) == 0) {
  79.         switch (mail_probe (nmf->filename,&type)) { /* can we read this? */
  80.         case PR_NAME:
  81.         break;
  82.         case PR_NOEX:
  83.         break;
  84.         case PR_PERM:
  85.         if (!quiet)
  86.             cmxprintf("?Cannot read file: %s\n", nmf->filename);
  87.         break;
  88.         case PR_EMPTY:
  89.         unlink(nmf->filename);
  90.         break;        
  91.         case PR_NOTOK:
  92.         if (!quiet)
  93.             cmxprintf("?File is damaged or in unknown format: %s\n",
  94.                   nmf->filename);
  95.         break;
  96.         default:
  97.         nmf->type = type;
  98.         if (same_file (nmf->filename, cf->filename)) {
  99.             if (!quiet)
  100.             cmxprintf ("?Primary mail file cannot be %s.\n",
  101.                    nmf->filename);
  102.             nmreturn (result);
  103.         }
  104.         if (!fetchmail(nmf,nil)) {
  105.             nf = nmf;
  106.             nmreturn (result);
  107.         }
  108.         }
  109.     }
  110.     }
  111.  
  112.     if (incoming_mail == NULL) {
  113.     incoming_mail = (keylist) malloc(2 * sizeof(char *));
  114.     incoming_mail[0] = malloc(strlen(user_name) + 
  115.                   sizeof (SPOOL_DIRECTORY) + 2);
  116.     sprintf(incoming_mail[0], "%s/%s", SPOOL_DIRECTORY, user_name);
  117.     incoming_mail[1] = NULL;
  118.     }
  119.     for(i = incoming_mail; i && *i; i++) {
  120.     switch (mail_probe (*i, &type))    { /* can we read this? */
  121.     case PR_NAME:
  122.         if (!quiet)
  123.         cmxprintf("?Badly formed filename: %s\n", *i);
  124.         continue;
  125.     case PR_NOEX:
  126.         continue;
  127.     case PR_PERM:
  128.         if (!quiet)
  129.         cmxprintf("?Cannot read file: %s\n", *i);
  130.         continue;
  131.     case PR_EMPTY:
  132.         continue;
  133.     case PR_NOTOK:
  134.         if (!quiet)
  135.         cmxprintf("?File is damaged or in unknown format: %s\n", *i);
  136.         continue;
  137.     }
  138.  
  139.     if (stat(*i,&sbuf) < 0)
  140.         continue;
  141.     if ((cf == NULL) || (cf->flags & MF_RDONLY) || 
  142.         !(cf->flags & MF_MAILBOX)) {
  143.         if (sbuf.st_mtime > oldbuf.st_mtime || !quiet) {
  144.         printf("You have new mail in %s.\n", *i);
  145.         if (sbuf.st_mtime > mailbuf.st_mtime)
  146.             mailbuf = sbuf;
  147.         sawmail = true;
  148.         }
  149.         continue;
  150.     }
  151.  
  152.     nf = (msgvec *) malloc(sizeof(msgvec));
  153.     bzero(nf,sizeof(msgvec));
  154.     nf->type = type;
  155.     if (same_file (cf->filename, nf->filename))
  156.         cmxprintf ("\
  157. ?Cannot read incoming mail file %s that is primary mail file\n", *i);
  158.     else {
  159.         if (move_mail (*i, strcmp(mail_directory,".")?mail_directory:HOME,
  160.         tempfile, quiet) != 0)
  161.         nmreturn (result);
  162.         sprintf(nf->filename,"%s/%s", 
  163.             strcmp(mail_directory,".")?mail_directory:HOME, tempfile);
  164.         if (!fetchmail(nf,*i))
  165.         return(true);
  166.     }
  167.     }
  168.     result = sawmail || gotmail;
  169.     nmreturn (result);
  170. }
  171.  
  172. fetchmail(nf,name)
  173. msgvec *nf;
  174. char *name;
  175. {
  176.     int j, err;
  177.     keylist k, free_keylist(), add_keyword();
  178.     extern FILE *header_pipe;
  179.     FILE *more_pipe_open();
  180.     extern int append_new_mail;
  181.  
  182.     if ((*msg_ops[nf->type].open)(nf,0) != 0) { /* open file */
  183.     cmxprintf("?Could not open %s.\n", nf->filename);
  184.     if (name != nil) {
  185.         cmxprintf("%s was moved to %s!\n", name, nf->filename);
  186.     }
  187.     return(false);
  188.     }
  189.     in_here = true;            /* read the mail in. */
  190.     cf->msgs = (message *)safe_realloc(cf->msgs, (cf->count + nf->count + 1) *
  191.                   sizeof(message));
  192.     if (!cf->msgs) {
  193.     fprintf (stderr, "Out of memory!  New mail is in %s\n",
  194.          nf->filename);
  195.     fflush (stderr);        /* just in case */
  196.     return(false);
  197.     }             
  198.     bcopy(&nf->msgs[1], &cf->msgs[cf->count+1],
  199.       nf->count * sizeof(message));
  200.     if (!gotmail)
  201.     printf("\007");            /* XXX add newline? flush bell? */
  202.     if (nf->count >= cmcsb._cmrmx)
  203.     header_pipe = more_pipe_open(cmcsb._cmoj);
  204.     else
  205.     header_pipe = cmcsb._cmoj;
  206.     header_print(0);
  207.     for (j = cf->count+1; j <= cf->count + nf->count; j++) {
  208.     cf->msgs[j].flags |= (M_RECENT|M_MODIFIED);
  209.     header_print(j);
  210.     }
  211.     header_print(-1);
  212.     if (header_pipe == cmcsb._cmoj) {    /* didn't open the pipe */
  213.     if (cmcsb._cmoj)
  214.         fflush(cmcsb._cmoj);
  215.     }
  216.     else
  217.     more_pipe_close(header_pipe);
  218.     header_pipe = NULL;
  219.  
  220.     cf->count += nf->count;
  221.     
  222.     for(k = nf->keywords; k && *k; k++)
  223.     cf->keywords = add_keyword(*k, cf->keywords);
  224.     nf->keywords = free_keylist(nf->keywords);
  225.     /*
  226.      * Grow the sequence-encoding bit vectors if necessary.
  227.      * Zeroing the new bits isn't necessary since the sequence
  228.      * is explicitly bounded by <sequence_t>->last.
  229.      */
  230.     if (!((sequence_bits(cf->sequence) = (unsigned char *)
  231.        realloc (sequence_bits(cf->sequence), cf->count/NBBY+1)) &&
  232.       (sequence_bits(cf->prev_sequence) = (unsigned char *)
  233.        realloc (sequence_bits(cf->prev_sequence), cf->count/NBBY+1)) &&
  234.       (sequence_bits(cf->read_sequence) = (unsigned char *)
  235.        realloc (sequence_bits(cf->read_sequence), cf->count/NBBY+1))))
  236.     panic("out of memory in newmail");
  237.     
  238.     if (append_new_mail == SET_NO) {
  239.     cf->flags |= MF_DIRTY;        /* make sure all mail gets saved */
  240.     err = !update(&cf,UPD_ALWAYS);
  241.     }
  242.     else {
  243.     err = !apnd_update(&cf, nf->count); /* save by appending */
  244.     if (err)
  245.         cf->flags |= MF_DIRTY;    /* will update next time around */
  246.     }
  247.  
  248.     if (err) {                /* can we save it? */
  249. #ifdef EDQUOT
  250.     if (errno == EDQUOT) {
  251.         fprintf(stderr, "\n\
  252. Try suspending MM, and making space by deleting some files.  Then, use the\n\
  253. WRITE command to save your new mail!  If you can't make any space, your mail\n\
  254. is still in %s, and the new messages are in %s\n",
  255.             mail_file, nf->filename);
  256.     }
  257.     else 
  258. #endif /* BSD */
  259.     {
  260.         if (name != NULL)
  261.         fprintf (stderr,"New mail from %s has been moved to %s\n",
  262.              name, nf->filename);
  263.     }
  264.     alarm(0);
  265.     return(false);
  266.     }
  267.     else {
  268.     in_here = false;
  269.     unlink(nf->filename);    /* it's saved, delete the new mail */
  270.     (*msg_ops[nf->type].close)(nf->filep);
  271.     free (nf->msgs);
  272.     free (nf);
  273.     nf = nil;
  274.     }
  275.     gotmail = true;
  276.     return(true);
  277. }
  278.  
  279. move_mail(from, todir, tofile, quiet)
  280. char *from, *todir, *tofile;
  281. int quiet;
  282. {
  283.     int ret;
  284.     extern string movemail_path;
  285.     char *movemail_argv[4];
  286.     char buf[MAXPATHLEN];
  287.     
  288.     movemail_argv[0] = movemail_path;
  289.     movemail_argv[1] = from;
  290.     sprintf(buf,"%s/%s", todir, tofile);
  291.     movemail_argv[2] = buf;
  292.     movemail_argv[3] = nil;
  293.  
  294.     fix_signals_for_fork (true);
  295.     ret = mm_execute(movemail_path, movemail_argv);
  296.     fix_signals_for_fork (false);
  297.     if (ret != 0 && !quiet)
  298.       fprintf (stderr, "Could not get mail from %s\n", from);
  299.     return (ret);
  300. }
  301.